#include "DlgStructure3D.h"
#include <QDir>
#include <QFileInfo>
#include <QFileDialog>
#include <QStringList>
#include <QMessageBox>
#include <QProcess>
#include <QTableView>
#include <QStandardItemModel>

using namespace std;

DlgStructure3D::DlgStructure3D() : QDialog()
{
    /* Sets up the GUI */
    ui.setupUi (this);
    m_pParent = NULL;
    m_pTableView = ui.tableViewStructure;
    m_pTableModel = NULL;
}

DlgStructure3D::DlgStructure3D(QWidget *parent) : QDialog(parent)
{
    /* Sets up the GUI */
    ui.setupUi (this);
    m_pParent = (DPGMTracking*)(parent);
    //int len = BuildRTKCommandFilter();

    m_pTableView = ui.tableViewStructure;
    m_pTableModel = NULL;
}

DlgStructure3D::~DlgStructure3D()
{
    if (m_pTableModel != NULL)
    {
        delete m_pTableModel;
        m_pTableModel = NULL;
    } 
}

void DlgStructure3D::UpdateTableDlgFromData(const vector<STRUCT_PROPT>& vStructProperty)
{
    if (m_pParent == NULL)
        return;
    if (m_pParent->m_pRTstudy == NULL)
        return;

    if (vStructProperty.empty())
        return;

    if (m_pTableModel != NULL)
    {
        delete m_pTableModel;
        m_pTableModel = NULL;
    }

    int columnSize = 12;
    int rowSize = vStructProperty.size();

    m_pTableModel = new QStandardItemModel(rowSize, columnSize, this); //2 Rows and 3 Columns
    m_pTableModel->setHorizontalHeaderItem(0, new QStandardItem(QString("ID")));
    m_pTableModel->setHorizontalHeaderItem(1, new QStandardItem(QString("Name")));
    m_pTableModel->setHorizontalHeaderItem(2, new QStandardItem(QString("NumOfPoints")));
    m_pTableModel->setHorizontalHeaderItem(3, new QStandardItem(QString("Color")));

    m_pTableModel->setHorizontalHeaderItem(4, new QStandardItem(QString("2DThick")));
    m_pTableModel->setHorizontalHeaderItem(5, new QStandardItem(QString("2DVsble")));
    m_pTableModel->setHorizontalHeaderItem(6, new QStandardItem(QString("2DSparse")));
    m_pTableModel->setHorizontalHeaderItem(7, new QStandardItem(QString("2DMotion")));

    m_pTableModel->setHorizontalHeaderItem(8, new QStandardItem(QString("3DThick")));
    m_pTableModel->setHorizontalHeaderItem(9, new QStandardItem(QString("3DVsble")));
    m_pTableModel->setHorizontalHeaderItem(10, new QStandardItem(QString("3DSparse")));
    m_pTableModel->setHorizontalHeaderItem(11, new QStandardItem(QString("3DMotion")));

    //int i = fixedY;
    STRUCT_PROPT curData;
    int iVisible2D = 0;
    int iVisible3D = 0;

    for (int i = 0; i < rowSize; i++)
    {
        curData = vStructProperty.at(i);

        if (curData.bVisible2D)
            iVisible2D = 1;
        else
            iVisible2D = 0;

        if (curData.bVisible3D)
            iVisible3D = 1;
        else
            iVisible3D = 0;

        int iMotionLink2D = 0;
        int iMotionLink3D = 0;

        if (curData.bMotionEnable2D)
            iMotionLink2D = 1;
        else
            iMotionLink2D = 0;

        if (curData.bMotionEnable3D)
            iMotionLink3D = 1;
        else
            iMotionLink3D = 0;

        m_pTableModel->setItem(i, 0, new QStandardItem(QString("%1").arg(curData.structID)));
        m_pTableModel->setItem(i, 1, new QStandardItem(curData.structName));
        m_pTableModel->setItem(i, 2, new QStandardItem(QString("%1").arg(curData.iNumOfPoints)));
        m_pTableModel->setItem(i, 3, new QStandardItem(QString("%1/%2/%3").arg(curData.fColor.fX).arg(curData.fColor.fY).arg(curData.fColor.fZ)));

        m_pTableModel->setItem(i, 4, new QStandardItem(QString("%1").arg(curData.iThick2D)));
        m_pTableModel->setItem(i, 5, new QStandardItem(QString("%1").arg(iVisible2D)));
        m_pTableModel->setItem(i, 6, new QStandardItem(QString("%1").arg(curData.iSparsity2D)));
        m_pTableModel->setItem(i, 7, new QStandardItem(QString("%1").arg(iMotionLink2D)));

        m_pTableModel->setItem(i, 8, new QStandardItem(QString("%1").arg(curData.iThick3D)));
        m_pTableModel->setItem(i, 9, new QStandardItem(QString("%1").arg(iVisible3D)));
        m_pTableModel->setItem(i, 10, new QStandardItem(QString("%1").arg(curData.iSparsity3D)));
        m_pTableModel->setItem(i, 11, new QStandardItem(QString("%1").arg(iMotionLink3D)));        
    }    

    m_pTableView->setModel(m_pTableModel);
    m_pTableView->resizeColumnsToContents();
}


//Do not change structure name, and so on!
void DlgStructure3D::UpdateDataFromTableDlg(vector<STRUCT_PROPT>& vStructProperty)
{
    QStringList list;

    int rowCnt = m_pTableModel->rowCount();
    int columnCnt = m_pTableModel->columnCount();

    /*if (columnCnt != 12)
        return;
    if (rowCnt < 1)
        return;*/

    QStandardItem* tableItem[12];

    if (columnCnt != 12)
        return;
    
    
    vStructProperty.clear();

    STRUCT_PROPT curData;
    for (int j = 0; j < rowCnt; j++)
    {
        for (int i = 0; i < columnCnt; i++)
        {            
            tableItem[i] = m_pTableModel->item(j, i);
        }        
        //12 items are ready
        //atableItem[0]->text()
        curData.structID = tableItem[0]->text().toInt();
        curData.structName = tableItem[1]->text();
        curData.iNumOfPoints = tableItem[2]->text().toInt();

        //curData.fColor = {}
        QString strColor = tableItem[3]->text();
        QStringList strlistColor = strColor.split("/");
        if (strlistColor.count() == 3)
        {
            curData.fColor.fX = strlistColor.at(0).toFloat();
            curData.fColor.fY = strlistColor.at(1).toFloat();
            curData.fColor.fZ = strlistColor.at(2).toFloat();
        }       
        
        curData.iThick2D = tableItem[4]->text().toInt();
        int iVisible2D = tableItem[5]->text().toInt();
        if (iVisible2D != 0)
            curData.bVisible2D = true;
        else
            curData.bVisible2D = false;
                
        curData.iSparsity2D = tableItem[6]->text().toInt();
        
        int iMotionLink2D = tableItem[7]->text().toInt();
        if (iMotionLink2D != 0)
            curData.bMotionEnable2D = true;
        else
            curData.bMotionEnable2D = false;
        

        //3D
        curData.iThick3D = tableItem[8]->text().toInt();
        int iVisible3D = tableItem[9]->text().toInt();
        if (iVisible3D != 0)
            curData.bVisible3D = true;
        else
            curData.bVisible3D = false;

        curData.iSparsity3D = tableItem[10]->text().toInt();

        int iMotionLink3D = tableItem[11]->text().toInt();
        if (iMotionLink3D != 0)
            curData.bMotionEnable3D = true;
        else
            curData.bMotionEnable3D = false;

        vStructProperty.push_back(curData);
    }
}

void DlgStructure3D::SLT_OpenRS()
{
    /*QString dirPath = QFileDialog::getExistingDirectory(this, tr("Open RTK bin Directory"),
                "", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);*/

    //QString strPath = QFileDialog::getOpenFileNames(this, "Select DICOM RTSS file",
    //    "D:\\", "DICOM RT structure (*.dcm)");

    QString strPath = QFileDialog::getOpenFileName(this, "Select DICOM RTSS file", "D:\\", "DICOM RT structure (*.dcm)", 0, 0);

    if (strPath.length() < 3)
        return;

    m_pParent->LoadRTStruct(strPath);
    ui.plainTextPath->appendPlainText(strPath);
}

void DlgStructure3D::SLT_UpdateTableFromData()
{
    m_pParent->UpdateStructureTable(UT_DATA2TABLE);//Get m_vStructureProperty
}

void DlgStructure3D::SLT_UpdateDataFromTable()
{
    m_pParent->UpdateStructureTable(UT_TABLE2DATA); //fill m_vStructureProperty
    
}

//
//void DlgExternalCommand::SLT_SetRTKPath()
//{
//	QString dirPath = QFileDialog::getExistingDirectory(this, tr("Open RTK bin Directory"),
//		"", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
//
//
//	if (dirPath.length() > 1)
//	{
//		SetRTKBinPath(dirPath);
//	}
//}
//
//void DlgExternalCommand::SetRTKBinPath(QString& strDirPath)
//{
//	//If DIr is exist
//	QDir dirInfo = QDir(strDirPath);
//
//	if (!dirInfo.exists())
//	{
//		cout << "ERROR! " << strDirPath.toLocal8Bit().constData() << " doesn't exist." << endl;
//		return;
//	}
//
//	ui.comboBoxRTKOption->clear();
//
//	m_strDirRTKBin = strDirPath;
//	ui.plainTextRTKPath->setPlainText(m_strDirRTKBin);
//
//	//Search for available commands
//	if (m_strDirRTKBin.isEmpty())
//		return;
//	
//	int cnt = m_listRTKCommandFilter.length();
//
//	QString tmpStrPath;
//
//	for (int i = 0; i < cnt; i++)
//	{
//		QString strCommandFilter = m_listRTKCommandFilter.at(i);
//		tmpStrPath = m_strDirRTKBin;
//		tmpStrPath = tmpStrPath.append("\\").append(strCommandFilter).append(".exe");
//
//		cout << m_strDirRTKBin.toLocal8Bit().constData() << endl;
//		cout << tmpStrPath.toLocal8Bit().constData() << endl;
//
//		QFileInfo fInfo = QFileInfo(tmpStrPath);
//		if (fInfo.exists()) //add combo
//		{
//			ui.comboBoxRTKOption->addItem(strCommandFilter);
//		}
//	}
//}
//
//void DlgExternalCommand::SLT_GenRTKCommand()
//{
//	QString crntPath = ui.plainTextRTKPath->toPlainText();
//	QString crntCommand = ui.comboBoxRTKOption->currentText();
//	
//	QString strFinalCommandText;
//
//	if (crntCommand.length() > 0 && crntPath.length() > 0)
//	{
//		strFinalCommandText = crntPath.append("\\").append(crntCommand);
//	}
//	else
//		return;
//
//	//QString strGeometry;
//	QString strOutput; //this should be member and unique //this is float format
//	//QString strHardware;
//	//QString strTruncation;
//	//QString strHann;
//	//QString strHannY;
//
//	//QString strProjPath;
//	//QString strRegExp;	
//	//QString strOutOrigin; //default: centered
//	//QString strOutDimension;
//	//QString strOutSpacing;
//	//QString strOutDirection; //no clue about what it is	
//	
//	//geometry
//	QString str_mainGeometry = m_pParent->ui.lineEdit_ElektaGeomPath->text();
//
//	if (str_mainGeometry.length() < 1)
//		cout << "Command will not be valid. set geometry file path in the main UI first." << endl;
//
//	QString str_mainHardware;
//	if (m_pParent->ui.radioButton_UseCPU->isChecked())
//		str_mainHardware = "cpu";
//	else if (m_pParent->ui.radioButton_UseCUDA->isChecked())
//		str_mainHardware = "cuda";
//	else if (m_pParent->ui.radioButton_UseOpenCL->isChecked())
//		str_mainHardware = "opencl";
//
//	//QString str_mainTruncation;
//	double f_mainTrunc = m_pParent->ui.lineEdit_Ramp_TruncationCorrection->text().toDouble();
//	double f_mainHann = m_pParent->ui.lineEdit_Ramp_HannCut->text().toDouble();
//	double f_mainHannY = m_pParent->ui.lineEdit_Ramp_HannCutY->text().toDouble();
//
//	QString str_mainProjPath = m_pParent->ui.lineEdit_HisDirPath->text();
//
//	QString str_mainProjRegExp = ".*.his";
//
//	QString str_mainDimension = QString("%1,%2,%3")
//		.arg(m_pParent->ui.lineEdit_outImgDim_AP->text())
//		.arg(m_pParent->ui.lineEdit_outImgDim_SI->text())
//		.arg(m_pParent->ui.lineEdit_outImgDim_LR->text());
//
//	QString str_mainSpacing = QString("%1,%2,%3")
//		.arg(m_pParent->ui.lineEdit_outImgSp_AP->text())
//		.arg(m_pParent->ui.lineEdit_outImgSp_SI->text())
//		.arg(m_pParent->ui.lineEdit_outImgSp_LR->text());
//
//
//
//	QTime curTime = QTime::currentTime();
//	QString strTimeStamp = curTime.toString("hhmmss");
//	QDir tmpPlmDir = QDir(m_pParent->m_pDlgRegistration->m_strPathPlastimatch);
//	
//	if (!tmpPlmDir.exists())
//	{
//		cout << "Error! No tmp plm path is available." << tmpPlmDir.absolutePath().toLocal8Bit().constData() << endl;		
//		return;
//	}
//
//	strOutput = tmpPlmDir.absolutePath() + "\\" + "ExternalRtk_" + crntCommand + "_" + strTimeStamp + ".mha";
//
//	
//
//	if (crntCommand == "rtkfdk")
//	{
//		//For FDK, this is sure!	
//		strFinalCommandText = strFinalCommandText +
//			" --geometry " + str_mainGeometry +
//			" --path " + str_mainProjPath +
//			" --verbos" +
//			" --regexp " + str_mainProjRegExp +
//			" --output " + strOutput +
//			" --spacing " + str_mainSpacing +
//			" --dimension " + str_mainDimension +
//
//			" --hardware " + str_mainHardware +
//			" --pad " + QString("%1").arg(f_mainTrunc) +
//			" --hann " + QString("%1").arg(f_mainHann) +
//			" --hannY " + QString("%1").arg(f_mainHannY);
//	}
//	//ui
//	/*lineEditIteration
//		lineEditSARTlamda
//		lineEditSARTpositivity
//		lineEditSARTsubsetproj*/
//
//	
//	else if (crntCommand == "rtksart")
//	{		
//		QString strIteration = ui.lineEditIteration->text().trimmed(); //niterations default 5
//		QString strLamda = ui.lineEditSARTlamda->text().trimmed(); //Convergence factor : default 0.3
//		QString strPositivity = ui.lineEditSARTpositivity->text().trimmed();   //Enforces positivity during the reconstruction (default=off)",
//		QString strNprojpersubset = ui.lineEditSARTsubsetproj->text().trimmed(); //Number of projections processed between each update of the reconstructed volume (1 for SART, several for OSSART, all for SIRT)  (default=`1')",
//		QString strFwdMethod = "Joseph";
//		if (str_mainHardware == "cuda")
//			strFwdMethod = "CudaRayCast";
//			//			--fp = ENUM Forward projection method(possible values = \"Joseph\", \"RayCastInterpolator\", "CudaRayCast\" default=`Joseph')",
//
//		QString strBackMethod = "VoxelBasedBackProjection";
//		if (str_mainHardware == "cuda")
//			strBackMethod = "CudaVoxelBased";		
//
//		strFinalCommandText = strFinalCommandText +
//			" --geometry " + str_mainGeometry +
//			" --path " + str_mainProjPath +
//			" --verbos" +
//			" --regexp " + str_mainProjRegExp +			
//			" --spacing " + str_mainSpacing +
//			" --dimension " + str_mainDimension +
//
//			" --niterations " + strIteration +
//			" --lambda " + strLamda +
//			" --positivity " + strPositivity +
//			" --nprojpersubset " + strNprojpersubset +
//			" --fp " + strFwdMethod +
//			" --bp " + strBackMethod +
//			" --time " + "on" +
//			" --output " + strOutput;
//	}
//	else if (crntCommand == "rtkadmmtotalvariation")
//	{
//		//lineEditIteration
//		//lineEditTValpha
////			lineEditTVbeta
//	//		lineEditTVCGiter* /
//
//		QString strIteration = ui.lineEditIteration->text().trimmed(); //niterations default 5
//		QString strTValpha = ui.lineEditTValpha->text().trimmed(); //Convergence factor : default 0.3
//		QString strTVbeta = ui.lineEditTVbeta->text().trimmed();   //Enforces positivity during the reconstruction (default=off)",
//		QString strTVCGiter = ui.lineEditTVCGiter->text().trimmed();   //Enforces positivity during the reconstruction (default=off)",		
//		QString strFwdMethod = "Joseph";
//		if (str_mainHardware == "cuda")
//			strFwdMethod = "CudaRayCast";
//		//			--fp = ENUM Forward projection method(possible values = \"Joseph\", \"RayCastInterpolator\", "CudaRayCast\" default=`Joseph')",
//
//		QString strBackMethod = "VoxelBasedBackProjection";
//		if (str_mainHardware == "cuda")
//			strBackMethod = "CudaVoxelBased";
//
//		strFinalCommandText = strFinalCommandText +
//			" --geometry " + str_mainGeometry +
//			" --path " + str_mainProjPath +
//			" --verbos" +
//			" --regexp " + str_mainProjRegExp +			
//			" --spacing " + str_mainSpacing +
//			" --dimension " + str_mainDimension +
//			" --niterations " + strIteration +
//			" --alpha " + strTValpha +
//			" --beta " + strTVbeta +
//			" --CGiter " + strTVCGiter +
//			" --fp " + strFwdMethod +
//			" --bp " + strBackMethod +
//			" --time " + "on" +
//			" --output " + strOutput;
//	}
//	else if (crntCommand == "rtkadmmwavelets")
//	{
//		QString strIteration = ui.lineEditIteration->text().trimmed(); //niterations default 5
//		QString strTValpha = ui.lineEditTValpha->text().trimmed(); //Convergence factor : default 0.3
//		QString strTVbeta = ui.lineEditTVbeta->text().trimmed();   //Enforces positivity during the reconstruction (default=off)",
//		QString strTVCGiter = ui.lineEditTVCGiter->text().trimmed();   //Enforces positivity during the reconstruction (default=off)",		
//
//		QString strWVorder = ui.lineEditWVorder->text().trimmed();
//		QString strWVlevel = ui.lineEditWVlevel->text().trimmed();
//		//"      --order=INT         The order of the Daubechies wavelets  (default=`3')",
//		//"      --levels=INT        The number of decomposition levels in the wavelets \n                            transform  (default=`5')",	
//
//
//		QString strFwdMethod = "Joseph";
//		if (str_mainHardware == "cuda")
//			strFwdMethod = "CudaRayCast";
//		//			--fp = ENUM Forward projection method(possible values = \"Joseph\", \"RayCastInterpolator\", "CudaRayCast\" default=`Joseph')",
//
//		QString strBackMethod = "VoxelBasedBackProjection";
//		if (str_mainHardware == "cuda")
//			strBackMethod = "CudaVoxelBased";
//
//		strFinalCommandText = strFinalCommandText +
//			" --geometry " + str_mainGeometry +
//			" --path " + str_mainProjPath +
//			" --verbos" +
//			" --regexp " + str_mainProjRegExp +		
//			" --spacing " + str_mainSpacing +
//			" --dimension " + str_mainDimension +
//			" --niterations " + strIteration +
//			" --alpha " + strTValpha +
//			" --beta " + strTVbeta +
//			" --CGiter " + strTVCGiter +
//			" --fp " + strFwdMethod +
//			" --bp " + strBackMethod +
//			" --order " + strWVorder +
//			" --levels " + strWVlevel +
//			" --time " + "on" +
//			" --output " + strOutput;
//	}
//
//
//	m_strRecentOutputPath = strOutput;
//	ui.plainTextRTKCommandLine->setPlainText(strFinalCommandText);
//}
//
//void DlgExternalCommand::SLT_RunRTKCommand()
//{
//	QString strFinalExternalCommand = ui.plainTextRTKCommandLine->toPlainText();
//	if (QProcess::execute(strFinalExternalCommand) < 0)
//		qDebug() << "Failed to run";
//
//	cout << "External RTK reconstruction is done" << endl;
//	cout << "File is being loaded" << endl;
//
//	m_pParent->LoadExternalFloatImage(m_strRecentOutputPath, true); //true: conversion (float, direction
//	
//	if (m_pParent->ui.checkBox_PostMedianOn->isChecked())
//		m_pParent->MedianFilterByGUI();//applied to raw image
//
//	m_pParent->FileExportByGUI();//applied to raw image
//}
//
//int DlgExternalCommand::BuildRTKCommandFilter() //called when it is created
//{
//	//Search for some preset option file, later.
//	//Temporarily it is hard coded.	
//	m_listRTKCommandFilter.clear();
//
//	m_listRTKCommandFilter.push_back("rtksart");
//	m_listRTKCommandFilter.push_back("rtkfdk");
//	m_listRTKCommandFilter.push_back("rtkadmmtotalvariation");
//	m_listRTKCommandFilter.push_back("rtkadmmwavelets");
//	//m_listRTKCommandFilter.push_back("rtktotalvariationdenoising");
//	//m_listRTKCommandFilter.push_back("rtkwaveletsdenoising");
//	
//
//	return (m_listRTKCommandFilter.length());
//}
//
//void DlgExternalCommand::SLT_SetRTKPathManual()//apply button
//{
//	QString tmpPlainText = ui.plainTextRTKPath->toPlainText();
//	SetRTKBinPath(tmpPlainText);
//
//}
//
//
